<template>
  <span :class="style">{{ label }}</span>
</template>

<script setup lang="ts">
import {ref, watch} from 'vue';
import Layers from "@/lang/layers/index";
import setting from "@/widget/provider/setting";
import Dictionary from "@/lang/dict/dictionary";
import {UseDictionary, useDictionary} from "@/widget/use/use-dictionary";

/**
 * 数据字典
 *
 * 简单的文本转换，value 转换成 label，提供了异步加载的功能
 */
interface Props extends /* @vue-ignore */ UseDictionary {
    // 值字段名
    value?: string | boolean | number | undefined
    // 数据匹配方式：default（等值比较）、range（区间比较）
    type?: 'default' | 'range'
    // 默认的标签：未匹配数据时候展示的文本
    defaultLabel?: string
    // 默认样式：未匹配数据时展示的样式
    defaultClass?: string
    // 禁用样式：某些场景下，样式反而不利于布局，这时候可以禁用样式
    disabledStyle?: boolean

    /** 数据字典配置 */
    options: DictionaryItem[] | string
    /** 异步查询参数 */
    where?: Record<string, any>
    /** 异步获取字典数据的函数 */
    provider?: DictionaryQuery
}

// 使用 withDefaults 设置默认值
const props = withDefaults(defineProps<Props>(), {
    type: 'default',
    provider: () => setting.queryDictionary
})

// css样式
const style = ref('');
// 标签值
const label = ref(undefined);

// 当前使用的数据字典
let dictionary = Dictionary.DEF;

// 数据字典变化
const onchange = (dict) =>{
    dictionary = dict;
    match();
}

// 匹配数据字典的逻辑
const match = () => {
    if (Layers.isEmpty(props.value)) {
        // 如果值为空，也禁用样式
        label.value = props.defaultLabel;
        style.value = '';
    } else {
        // match item
        let item = props.type === 'default'
            ? dictionary.matchByValue(props.value, props.defaultLabel, props.defaultClass)
            : dictionary.matchByRange(props.value, props.defaultLabel, props.defaultClass)

        label.value = item.label;
        style.value = item.style;
    }
};

// 监听 props.value 的变化
watch(() => props.value, match);

const {opts, loading} = useDictionary(props, onchange);
</script>